package com.gome.ss.core.download;

import java.security.MessageDigest;
import java.util.concurrent.TimeoutException;

import com.gome.spiderkit.client.CookieJar;
import com.gome.spiderkit.client.UnknowServerException;
import com.gome.spiderkit.client.WebKit;
import com.gome.spiderkit.client.WebPage;
import com.gome.ss.core.queue.QueueCache;
import com.google.protobuf.InvalidProtocolBufferException;

public class SpiderRequest implements SpiderRequestInterface {
	
	private SpiderUrl url;
	private String groupName = "";
	private String pluginName = "";
	private String pluginQualified = "";
	private int priority = QueueCache.defaultPriority;
	private int retryCount = 0;
	private int triedCount = 0;
	private String sourceTaskID = "";
	private boolean isStatic = false;
	private Object cdata = null;
	
	private WebPage readyPage = null;
	private boolean isPageReady = false;
	private boolean isNewPageReady = false;
	private CookieJar cookies = null;
	
	private boolean isListPage = false;
	private String currentPage = "0";
	
	private String identity = "";
	private String incrementalID = "";
	private String identityMD5 = "";
	private String incrementalMD5ID = "";
	private boolean isIncremental = false;
	
	private void initMD5ID() {
		this.incrementalID = url.getLink() + groupName + pluginQualified +
				String.valueOf(isListPage) + currentPage;
		
		this.identity = this.incrementalID + String.valueOf(retryCount) + String.valueOf(triedCount) +
				sourceTaskID + String.valueOf(isPageReady) + String.valueOf(priority) + String.valueOf(isStatic);
		
		incrementalMD5ID = MD5(incrementalID);
		identityMD5 = MD5(identity);
	}
	
    private String MD5(String s) {
        char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};       

        try {
            byte[] btInput = s.getBytes();
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
	
	private SpiderRequest(String link, String groupName, String pluginName, String pluginQualified) {
		this.url = new SpiderUrl(link);
		this.groupName = groupName;
		this.pluginName = pluginName;
		this.pluginQualified = pluginQualified;
		initMD5ID();
	}
	
	private SpiderRequest(String link, String groupName, String pluginName, String pluginQualified, int priority, int retryCount) {
		this.url = new SpiderUrl(link);
		this.groupName = groupName;
		this.pluginName = pluginName;
		this.pluginQualified = pluginQualified;
		this.priority = priority;
		this.retryCount = retryCount;
		initMD5ID();
	}
	
	public static SpiderRequestInterface create(String link, String groupName, String pluginName, String pluginQualified) {
		SpiderRequest request = new SpiderRequest(link, groupName, pluginName, pluginQualified);
		return request;
	}
	
	public static SpiderRequestInterface create(String link, String groupName, String pluginName, String pluginQualified, int priority, int retryCount) {
		SpiderRequest request = new SpiderRequest(link, groupName, pluginName, pluginQualified, priority, retryCount);
		return request;
	}
	
	public static SpiderRequestInterface create(String link, String groupName, String pluginName, String pluginQualified, CookieJar cookies, int priority, int retryCount) {
		SpiderRequest request = new SpiderRequest(link, groupName, pluginName, pluginQualified, priority, retryCount);
		request.cookies = cookies;
		return request;
	}
	
	public static SpiderRequestInterface createStatic(String link, String groupName, String pluginName, String pluginQualified) {
		SpiderRequest request = new SpiderRequest(link, groupName, pluginName, pluginQualified);
		request.setStatic();
		return request;
	}
	
	public static SpiderRequestInterface createStatic(String link, String groupName, String pluginName, String pluginQualified, int priority, int retryCount) {
		SpiderRequest request = new SpiderRequest(link, groupName, pluginName, pluginQualified, priority, retryCount);
		request.setStatic();
		return request;
	}
	
	public static SpiderRequestInterface createPageReady(
		WebPage page, String pluginName, String pluginQualified, int retryCount
	) throws InvalidProtocolBufferException, UnknowServerException, TimeoutException {
		if (page == null)
			return null;
		
		String link = page.getUrl();
		SpiderRequest request = new SpiderRequest(link, "", pluginName, pluginQualified, QueueCache.defaultPriority, retryCount);
		request.isPageReady = true;
		request.readyPage = page;
		request.initMD5ID();
		return request;
	}
	
	public static SpiderRequestInterface createPageReady(
		WebPage page, boolean newPage, String pluginName, String pluginQualified, int retryCount
	) throws InvalidProtocolBufferException, UnknowServerException, TimeoutException {
		if (page == null)
			return null;
		
		String link = page.getUrl();
		SpiderRequest request = new SpiderRequest(link, "", pluginName, pluginQualified, QueueCache.defaultPriority, retryCount);
		request.isPageReady = true;
		request.readyPage = page;
		request.initMD5ID();
		request.isNewPageReady = true;
		return request;
	}
	
	@Override
	public SpiderUrl getUrl() {
		// TODO Auto-generated method stub
		return url;
	}

	@Override
	public String getGroupName() {
		// TODO Auto-generated method stub
		return groupName;
	}
	
	@Override
	public String getPluginName() {
		// TODO Auto-generated method stub
		return pluginName;
	}

	@Override
	public String getPluginQualified() {
		// TODO Auto-generated method stub
		return pluginQualified;
	}

	@Override
	public int getPriority() {
		// TODO Auto-generated method stub
		return priority;
	}

	@Override
	public void setSourceTaskID(String taskID) {
		// TODO Auto-generated method stub
		this.sourceTaskID = taskID;
		initMD5ID();
	}
	
	@Override
	public String getSourceTaskID() {
		// TODO Auto-generated method stub
		return sourceTaskID;
	}
	
	@Override
	public int retryCount() {
		// TODO Auto-generated method stub
		return retryCount;
	}

	@Override
	public int triedCount() {
		// TODO Auto-generated method stub
		return triedCount;
	}
	
	public boolean accumulationTryTimes() {
		if (this.triedCount >= this.retryCount)
			return false;
		
		this.triedCount ++;
		initMD5ID();
		return true;
	}
	
	public boolean canRetry() {
		if (this.triedCount >= this.retryCount)
			return false;
		return true;
	}

	public void setStatic() {
		this.isStatic = true;
		initMD5ID();
	}
	
	@Override
	public boolean getIsStatic() {
		// TODO Auto-generated method stub
		return isStatic;
	}

	@Override
	public void carryData(Object data) {
		// TODO Auto-generated method stub
		cdata = data;
	}

	@Override
	public Object getData() {
		// TODO Auto-generated method stub
		return cdata;
	}

	@Override
	public boolean isPageReady() {
		// TODO Auto-generated method stub
		return this.isPageReady;
	}
	
	@Override
	public boolean isNewPageReady() {
		// TODO Auto-generated method stub
		return this.isNewPageReady;
	}
	
	public void setIsPageReady(boolean ready) {
		this.isPageReady = ready;
	}
	
	public void setIsNewPageReady(boolean nready) {
		this.isNewPageReady = nready;
	}
	
	public WebPage getReadyPage() {
		// TODO Auto-generated method stub
		return this.readyPage;
	}

	@Override
	public String getIdentity() {
		// TODO Auto-generated method stub
		return this.identity;
	}
	
	@Override
	public String getID() {
		// TODO Auto-generated method stub
		return this.identityMD5;
	}

	@Override
	public CookieJar cookies() {
		// TODO Auto-generated method stub
		return cookies;
	}

	@Override
	public boolean isListPage() {
		// TODO Auto-generated method stub
		return this.isListPage;
	}

	@Override
	public String currentPage() {
		// TODO Auto-generated method stub
		return this.currentPage;
	}

	@Override
	public void setListPage(boolean isListPage) {
		// TODO Auto-generated method stub
		this.isListPage = isListPage;
		initMD5ID();
	}

	@Override
	public void setCurrentPage(String currentPage) {
		// TODO Auto-generated method stub
		this.currentPage = currentPage;
		initMD5ID();
	}

	@Override
	public String getIncrementalID() {
		// TODO Auto-generated method stub
		return this.incrementalID;
	}
	
	@Override
	public String getIID() {
		// TODO Auto-generated method stub
		return this.incrementalMD5ID;
	}
	
	@Override
	public boolean isIncremental() {
		// TODO Auto-generated method stub
		return isIncremental;
	}

	@Override
	public void setIncremental(boolean isIncremental) {
		// TODO Auto-generated method stub
		this.isIncremental = isIncremental;
	}
	
}
